package com.vercon.commonmirror.network

import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.net.UnknownHostException

class RetryInterceptor(private val domainList:List<String>): Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()

        var response = doRequest(chain, request)
        val url = request.url.toString()

		//判断是否域名无效，接口是否请求失败
		//条件满足则进行域名替换
        if (response==null||!response.isSuccessful) {
            response = tryRequest(chain, request,response, url, 0)
        }
		//如何response为空就抛出异常，不返回
        if (response==null) throw UnknownHostException()
        return response
    }

	//获取response
    private fun doRequest(chain: Interceptor.Chain, request: Request, response: Response?=null): Response? {
        var newResponse: Response? = null
        try {
        	//重新发起请求前需要先关闭response，否则会发生无效的请求，会打印日志如下：
        	//HTTP FAILED: java.lang.IllegalStateException: cannot make a new request because the previous response is still open: please call response.close()
            response?.close()
            newResponse = chain.proceed(request)
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return newResponse
    }

    private fun tryRequest(chain: Interceptor.Chain, request: Request, response: Response?, url: String, tryCount: Int):Response? {
        //防止无限循环，只走一遍域名列表
        if (tryCount+1>=domainList.size)return response
        //替换域名
        val newUrl  = switchServer(url,tryCount % domainList.size,(tryCount+1)%domainList.size)
        //重新创建请求对象
        val newRequest = request.newBuilder()
            .url(newUrl)
            .build()
        val newResponse = doRequest(chain,newRequest,response)
        //如果newResponse为null，这域名无效，继续切换
        return newResponse?.let {
        	//判断请求是否成功，不成功则重新尝试切换域名
            if(!it.isSuccessful){
                tryRequest(chain, request,newResponse, newUrl, tryCount+1)
            }else{
                return newResponse
            }
        }?: kotlin.run { tryRequest(chain, request,newResponse, newUrl, tryCount+1) }
    }

	//更改域名后，返回的URL地址
    private fun switchServer(url: String, oldIndex: Int, newIndex: Int): String {
        var newUrlString = url
        if (newIndex < domainList.size || oldIndex < domainList.size) {
            val oldAddr: String = domainList.get(oldIndex)
            val newAddr: String = domainList.get(newIndex)
            newUrlString = url.replace(oldAddr, newAddr)
        }
        return newUrlString
    }

}
